<?php
/**
 * GioCMS
 * 
 * LICENSE
 *
 * This source file is subject to the GNU GENERAL PUBLIC LICENSE Version 2 
 * that is bundled with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://www.gnu.org/licenses/gpl-2.0.txt
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@ninhgio.com so we can send you a copy immediately.
 * 
 * @copyright	Copyright (c) 2010-2011 GioCMS (http://cms.ninhgio.com)
 * @license		http://www.gnu.org/licenses/gpl-2.0.txt GNU GENERAL PUBLIC LICENSE Version 2
 * @author		NinhGio - ninhgio@gmail.com
 * @since		1.0
 */

class Modules_Core_Controllers_User extends Gio_Core_Controller
{
	/* ########################### Frontend Action ########################## */
	
	public function loginAction()
	{
		$request  = $this->getRequest();
		$return = $request->getParam('return');
		$this->view->return = $return;
		
		if ($request->isPost()) {
			$username = $request->getPost('username');
			$password = $request->getPost('password');
			$this->view->username = $username;
			$this->view->password = $password;
			
			$user = Modules_Core_Services_User::auth($username, $password, true);
			if (null == $user) {
				$this->view->error = true;
				$this->view->message = $this->view->TRANSLATOR->translator('user_login_error');
			} elseif ($user['status'] == 'inactive') {
				$this->view->error = true;
				$this->view->message = $this->view->TRANSLATOR->translator('user_login_inactive');
			} elseif ($user['status'] == 'active') {
				$user['last_login'] = date('Y-m-d H:i:s');
				Modules_Core_Services_User::setLastLogin($user);
				
				$configs = Gio_Core_Config_Xml::getConfig('session');			
				$json = new Services_JSON();
				$sessionId = session_id();
				$session = array(
							'session_id' => $sessionId,
							'created_date' => strtotime(date('Y-m-d H:i:s')),
							'last_update' => strtotime(date('Y-m-d H:i:s')),
							'lifetime'	=> (isset($configs->lifetime))
													? $configs->lifetime
													: 3600,
							'inactive_time'	=> (isset($configs->inactive_time))
													? $configs->inactive_time
													: 120,
							'data' => $json->encodeUnsafe($user),
							'status' => 'active',
						);
						
				Gio_Core_Session::add($session);
				
				$return = $request->getPost('return');
				$redirect = ($return) ? base64_decode(rawurldecode($return)) : $this->view->url('core_index_index');
				$this->redirect($redirect);
			}
		}
	}
	
	public function logoutAction()
	{
		$this->disableLayout();
		$this->setNoRender();
		
		Gio_Core_Session::destroy();
		$this->redirect($this->view->url('core_index_index'));
	}
	
	public function registerAction()
	{
		$request = $this->getRequest();
		
		if ($request->isPost()) {
			$userData = $request->getPost('user');
			$userData = Modules_Core_Services_User::validate($userData);
			
			/**
			 * Check user exist 
			 */
			if ($userData['username'] && Modules_Core_Services_User::getByUsername($userData['username'])) {
				$userData['messages_error'] = true;
				$userData['messages']['username'] = 'user_username_exist';
			}
			/**
			 * Check user exist 
			 */
			if ($userData['email'] && Modules_Core_Services_User::getByEmail($userData['email'])) {
				$userData['messages_error'] = true;
				$userData['messages']['email'] = 'user_email_exist';
			}
			
			
			if (isset($userData['messages_error']) && $userData['messages_error']) {
				$this->view->errorMessages = $userData['messages'];
				$this->view->userData = $userData;
				return;
			}
			
			$config = Gio_Core_Module::getConfig('core', true);
			if (!isset($config['user']['default_role_id'])
					|| (null == ($role = Modules_Core_Services_Role::getById($config['user']['default_role_id']))))
			{
				return;
			}
			$salt = md5(time());
			$user = array(
					'username' 	   => $userData['username'],
					'password' 	   => md5(md5($userData['password']) . $salt),
					'email'		   => $this->view->STRING->escape($userData['email']),					
					'fullname' 	   => $this->view->STRING->escape($userData['fullname']),
					'salt'		   => $salt, 
					'status'	   => 'active',
					'created_date' => date('Y-m-d H:i:s'),
					'role_id'	   => $role['role_id']
			);
			
			$userId = Modules_Core_Services_User::add($user);
			/**
			 * Send welcome mail
			 */
			Modules_Core_Services_User::registerSuccess($user['username'], $user['email']);
			
			Gio_Core_Messenger::getInstance()
								->addMessage($this->view->TRANSLATOR->translator('user_register_success'));
			$this->redirect($this->view->url('core_user_register'));
		}		
	}
	
    /* ########################### Backend Action ########################### */
	
	public function activateAction()
	{
		$this->setNoRender();
		$this->disableLayout();
		
		$request = $this->getRequest();
		if (!$request->isPost()) {
			return;
		}
		$response = 'RESULT_NOT_OK';
		$userId = $request->getPost('user_id');
		$user = Modules_Core_Services_User::getById($userId);
		
		if (null == $user){
			$this->getResponse()->setBody($response);
			return;	
		}
		
		$act = $request->getPost('act');
		switch ($act) {
			case 'activate':
				$status = 'active';
				break;
			case 'deactivate':
				$status = 'inactive';
				break;
		}
		$user['status'] = $status;
		$response = 'RESULT_OK';
		Modules_Core_Services_User::update($user);
		$this->getResponse()->setBody($response);
	}
	
	public function addAction()
	{
		$request = $this->getRequest();
		
		$roles = Modules_Core_Services_Role::getAllRoles();
		$this->view->roles = $roles;
		
		if ($request->isPost()) {
			$userData = $request->getPost('user');
			$userData = Modules_Core_Services_User::validate($userData);
			
			/**
			 * Check user exist 
			 */
			if ($userData['username'] && Modules_Core_Services_User::getByUsername($userData['username'])) {
				$userData['messages_error'] = true;
				$userData['messages']['username'] = 'user_username_exist';
			}
			/**
			 * Check user exist 
			 */
			if ($userData['email'] && Modules_Core_Services_User::getByEmail($userData['email'])) {
				$userData['messages_error'] = true;
				$userData['messages']['email'] = 'user_email_exist';
			}
			
			if (isset($userData['messages_error']) && $userData['messages_error']) {
				$this->view->errorMessages = $userData['messages'];
				$this->view->userData = $userData;
				return;
			}
			
			$salt = md5(time());
			$user = array(
					'username' 	   => $userData['username'],
					'password' 	   => md5(md5($userData['password']) . $salt),
					'email'		   => $this->view->STRING->escape($userData['email']),					
					'fullname' 	   => $this->view->STRING->escape($userData['fullname']),
					'salt'		   => $salt, 
					'status'	   => $userData['status'],
					'created_date' => date('Y-m-d H:i:s'),
					'role_id'	   => $userData['role_id']
			);
			$userId = Modules_Core_Services_User::add($user);
			Gio_Core_Messenger::getInstance()
								->addMessage($this->view->TRANSLATOR->translator('user_actions_add_success'));
			$this->redirect($this->view->url('core_user_add'));
		}
	}
	
	public function changepasswordAction()
	{
		$request = $this->getRequest();
		$user = $this->view->userLogin;
		
		if ($request->isPost()) {
			$userData = $request->getPost('user');
			$userData['password'] = $user->password;
			if ($userData['oldpassword']) {
				$userData['oldpassword'] = md5(md5($userData['oldpassword']) . $user->salt);
			} 
			$userData = Modules_Core_Services_User::validatePassword($userData);
			
			if (isset($userData['messages_error']) && $userData['messages_error']) {
				$this->view->errorMessages = $userData['messages'];
				$this->view->userData = $userData;
				return;
			}
			
			$newpassword = md5(md5($userData['newpassword']) . $user->salt);
			$user = array(
				'user_id'  => $user->user_id,
				'password' => $newpassword,
			);
			
			Modules_Core_Services_User::changepassword($user);
			Gio_Core_Messenger::getInstance()
								->addMessage($this->view->TRANSLATOR->translator('user_actions_changepassword_success'));
			$this->redirect($this->view->url('core_user_changepassword'));
		}
	}
	
	public function editAction()
	{
		$request = $this->getRequest();
		
		$userId = $request->getParam('user_id');
		$user = Modules_Core_Services_User::getById($userId);
		if (null == $user) {
			throw new Exception();
		}
		/**
		 * Hide user password 
		 */
		$user['password'] = null;
		$this->view->userData = $user;
		
		$roles = Modules_Core_Services_Role::getAllRoles();
		$this->view->roles = $roles;
		
		if ($request->isPost()) {
			$userData = $request->getPost('user');
			$userData = Modules_Core_Services_User::validate($userData);
			
			/**
			 * Check user exist 
			 */
			if ($userData['username'] && Modules_Core_Services_User::getByUsername($userData['username'], $userId)) {
				$userData['messages_error'] = true;
				$userData['messages']['username'] = 'user_username_exist';
			}
			/**
			 * Check user exist 
			 */
			if ($userData['email'] && Modules_Core_Services_User::getByEmail($userData['email'], $userId)) {
				$userData['messages_error'] = true;
				$userData['messages']['email'] = 'user_email_exist';
			}
			
			if (isset($userData['messages_error']) && $userData['messages_error']) {
				$this->view->errorMessages = $userData['messages'];
				$userData['user_id'] = $userId;
				$this->view->userData = $userData;
				return;
			}
			$salt = $user['salt'];
			$user = array(
					'user_id'	   => $userId,
					'username' 	   => $userData['username'],
					'password' 	   => md5(md5($userData['password']) . $salt),
					'email'		   => $this->view->STRING->escape($userData['email']),					
					'fullname' 	   => $this->view->STRING->escape($userData['fullname']),
					'salt'		   => $salt, 
					'status'	   => $this->view->STRING->escape($userData['status']),
					'role_id'	   => $userData['role_id']
			);
			
			Modules_Core_Services_User::update($user);
			Gio_Core_Messenger::getInstance()
								->addMessage($this->view->TRANSLATOR->translator('user_actions_edit_success'));
			$this->redirect($this->view->url('core_user_edit', $user));
		}
	}
	
	public function resetpasswordAction()
	{
		$configs = Gio_Core_Config_Xml::getConfig('web');
		$this->setTemplate($configs->admin->template);
		$this->setLayout('forgotpassword');
		
		$request = $this->getRequest();
		$encodeLink = $request->getParam('encoded_link');
		if (Modules_Core_Services_User::resetPassword($encodeLink)) {
			$message = $this->view->TRANSLATOR->translator('user_resetpassword_success');
		} else {
			$message = $this->view->TRANSLATOR->translator('user_resetpassword_error');
		}
		
		$this->view->message = $message;
	}
	
	public function forgotpasswordAction()
	{
		$configs = Gio_Core_Config_Xml::getConfig('web');
		$this->setTemplate($configs->admin->template);
		$this->setLayout('forgotpassword');
		
		$request = $this->getRequest();
		if ($request->isPost()) {
			$email = $request->getPost('email');
			if (!$email) {
				$this->view->error = $this->view->TRANSLATOR->translator('user_forgotpassword_email_notnull');
				return;
			}
			
			$user = Modules_Core_Services_User::checkEmailExist($email);
			if (null == $user) {
				$this->view->error = $this->view->TRANSLATOR->translator('user_forgotpassword_email_notexist');
				return;
			}
			
			$code = Gio_Core_String::generateString(50);
			$user['code'] = $code;
			Modules_Core_Services_User::update($user);
			Modules_Core_Services_User::sendPassword($user['username'], $user['email'], $code);
			
			Gio_Core_Messenger::getInstance()
								->addMessage($this->view->TRANSLATOR->translator('user_forgotpassword_send_success'));
			$this->redirect($this->view->url('core_user_forgotpassword'));
		}
	}
	
	public function listAction()
	{
		$request = $this->getRequest();
		
		$perPage = 20;
		$pageIndex = (int)$request->getParam('page_index');
		if (null == $pageIndex || '' == $pageIndex || $pageIndex < 0) {
			$pageIndex = 1;
		}
		$start = ($pageIndex - 1) * $perPage;
		$this->view->pageIndex = $pageIndex;
		
		$condition = array(
						'status' 			=> 'active',
						'search_form'		=> false,
		);
		$json = new Services_JSON();
		if ($request->isPost()) {
			$condition = $request->getPost('condition');
			$condition['search_form'] = true;
			$params = rawurlencode(base64_encode($json->encodeUnsafe($condition)));
		} else {
			$params = $request->getParam('q');
			($params != null)
				? ($condition = (array)$json->decode(rawurldecode(base64_decode($params))))
				: ($params = rawurlencode(base64_encode($json->encodeUnsafe($condition))));
		}

		$params = (empty($condition)) ? null : $params;
		$this->view->condition = $condition;
		$users = Modules_Core_Services_User::find($condition, $start, $perPage);
		$numUsers = Modules_Core_Services_User::count($condition);
		
		$this->view->users = $users; 
		
		$roles = Modules_Core_Services_Role::getAllRoles();
		$this->view->roles = $roles;
		
		// Pager
		require_once LIB_DIR . DS . 'PEAR' . DS . 'Pager' . DS . 'Sliding.php';
		$pagerPath = $this->view->url('core_user_list');
		$pagerOptions = array(
			'mode'       	=> 'Sliding',
			'append'   		=> false,
    		'perPage'    	=> $perPage,
    		'delta'      	=> 5,
			'urlVar'		=> 'page',
			'path'			=> $pagerPath,
			'fileName'		=> (null == $params) ? 'page-%d' : 'page-%d/?q=' . $params,
			'separator'		=> '',
			'nextImg' 		=> '<small class="icon arrow_right"></small>',
			'prevImg'		=> '<small class="icon arrow_left"></small>',
			'altNext'		=> '',
			'altPrev'		=> '',
			'altPage'		=> '',
    		'totalItems' 	=> $numUsers,
			'currentPage'	=> $pageIndex,
			'urlSeparator'	=> '/',
			'spacesBeforeSeparator' => 0,
			'spacesAfterSeparator' => 0,
			'curPageSpanPre' => '<a href="javascript: void();" class="current">',
			'curPageSpanPost' => '</a>'
		
		);
		$pager = new Pager_Sliding($pagerOptions);
		$this->view->pager = $pager;
	}
	
	public function profileAction()
	{
		$request = $this->getRequest();
	}
}